#import "sprite_game_enemy.h"

/*enemy status
*/
#define ENEMY_STATE_INVALID 0
#define ENEMY_STATE_STAND 1
#define ENEMY_STATE_MOVE 2
#define ENEMY_STATE_ATTACK 3
#define ENEMY_STATE_DIE 4

#define ENEMY_STATE_BOSS1_APPEAR 5
#define ENEMY_STATE_BOSS1_STAGE_CHANGE 6
#define ENEMY_STATE_BOSS1_STRONG_ATTACK_MOVE_TO_START 7
#define ENEMY_STATE_BOSS1_STRONG_ATTACK_PLACE_BOMB 8
#define ENEMY_STATE_BOSS1_STRONG_ATTACK_ACTION 9

#define ENEMY_STATE_BOSS2_APPEAR 10
#define ENEMY_STATE_BOSS2_STAGE_CHANGE 11
#define ENEMY_STATE_BOSS2_STRONG_ATTACK 12


/*boss1 stage
*/
#define BOSS_1_STAGE_1 0
#define BOSS_1_STAGE_2 1
#define BOSS_1_STAGE_3 2

/*boss2 stage
*/
#define BOSS_2_STAGE_1 0
#define BOSS_2_STAGE_2 1
#define BOSS_2_STAGE_3 2

/*boss3 stage
*/

/*touch type
*/
#define ENEMY_TOUCH_TYPE_INVALID 0
#define ENEMY_TOUCH_TYPE_BOSS_3_QTE 1

/*time define
*/
#define ENEMY_DAMAGE_TINT_TIME 0.2
#define SPRITE_GAME_ENEMY_BOSS_3_SPECIAL_ATTACK_TIME 15.0f

#if (HARD_WARE == HARD_WARE_IPHONE)
	#define SPRITE_GAME_ENEMY_BOSS_3_MASK_FONT_SIZE 16
#elif (HARD_WARE == HARD_WARE_IPAD)
	#define SPRITE_GAME_ENEMY_BOSS_3_MASK_FONT_SIZE 24
#endif

@implementation sprite_game_enemy

@synthesize type = type_;
@synthesize state = state_;
@synthesize lifePoint = lifePoint_;
@synthesize box2dBody = box2dBody_;
@synthesize fixtureBody = fixtureBody_;
@synthesize fixtureArmor = fixtureArmor_;
@synthesize image = image_;
@synthesize effectShockWave = effectShockWave_;
@synthesize effectCover = effectCover_;
@synthesize lifeBar = lifeBar_;
@synthesize flagBoss2Stage = flagBoss2Stage_;
@synthesize mouthHeartHandle = mouthHeartHandle_;
@synthesize mosquitoHeartHandle = mosquitoHeartHandle_;
@synthesize boss3Handle = boss3Handle_;
@synthesize boss3SlaveLeftHandle = boss3SlaveLeftHandle_;
@synthesize boss3SlaveRightHandle = boss3SlaveRightHandle_;

- (id)initSpriteGameEnemy:(SMissionEnemy *)InfoData;
{
	int i;
	NSString *_Path;
	std::vector<SMissionEnemyPathElement>::iterator _PathIter;

	if ((self = [super init]))
	{
		/*set up tick
		*/

		/*set up base data
		*/

		/*born position or move path
		*/

		/*box2d
		*/
		[self CreateBody];

		/*image
		*/
		switch (type_)
		{
		case ENEMY_TYPE_0:
		case ENEMY_TYPE_1:
		case ENEMY_TYPE_2:
		case ENEMY_TYPE_3:
		case ENEMY_TYPE_4:
		case ENEMY_TYPE_5:
		case ENEMY_TYPE_6:
		case ENEMY_TYPE_7:
			lifePoint_ = g_CfgGameEnemyDataTable[type_].life_point;
			_Path = [NSString stringWithUTF8String:g_CfgGameEnemyDataTable[type_].default_image_path];
			image_ = [[CCSprite alloc] initWithSpriteFrameName:_Path];
			[self addChild:image_];
			[image_ release];
			break;
		case ENEMY_TYPE_BOSS_1:
			lifePoint_ = g_CfgGameBoss1Data.life_point;
			_Path = [NSString stringWithUTF8String:g_CfgGameBoss1Data.default_image_path];
			image_ = [[CCSprite alloc] initWithSpriteFrameName:_Path];
			[self addChild:image_];
			[image_ release];
			/*tail left
			*/
			tailLeft_ = [[sprite_game_enemy_tail alloc] initSpriteGameEnemyTail:true];
			tailLeft_.tailY = g_CfgGameScrrenArea[0].center.y - 50;
			tailLeft_.positionInPixels = ccp(0, tailLeft_.tailY);
			/*tail right
			*/
			tailRight_ = [[sprite_game_enemy_tail alloc] initSpriteGameEnemyTail:false];
			tailRight_.tailY = g_CfgGameScrrenArea[0].center.y + 50;
			tailRight_.positionInPixels = ccp(g_ScrrenSize.width, tailRight_.tailY);
			[g_LayerGameObject Boss1AddTail:tailLeft_ And:tailRight_];
			break;
		case ENEMY_TYPE_BOSS_2:
			lifePoint_ = g_CfgGameBoss2Data.life_point;
			_Path = [NSString stringWithUTF8String:g_CfgGameBoss2Data.default_image_path];
			image_ = [[CCSprite alloc] initWithSpriteFrameName:_Path];
			[self addChild:image_];
			[image_ release];
			/*skull
			*/
			[self AddSkull:ccp(0.0f, 230.0f) And:TRUE];
			[self AddSkull:ccp(0.0f, -230.0f) And:TRUE];
			[self AddSkull:ccp(230.0f, 0.0f) And:TRUE];
			[self AddSkull:ccp(-230.0f, 0.0f) And:TRUE];
			break;
		case ENEMY_TYPE_BOSS_3:
			lifePoint_ = g_CfgGameBoss3Data.life_point;
			/*image
			*/
			_Path = [NSString stringWithUTF8String:g_CfgGameBoss3Data.default_image_path];
			image_ = [[CCSprite alloc] initWithSpriteFrameName:_Path];
			[self addChild:image_];
			[image_ release];
			/*mask
			*/
			mask_ = [[sprite_game_enemy_mask alloc] initSpriteGameEnemyMask];
			[self addChild:mask_];
			[mask_ release];
			[mask_ runAction:[CCHide action]];
			/*eye
			*/
			for (i = 0; i < BOSS_3_QTE_EYE_COUNT; i++)
			{
				eye_[i] = [[sprite_game_enemy_eye alloc] initSpriteGameEnemyEye];
				[self addChild:eye_[i]];
				[eye_[i] release];
				[eye_[i] runAction:[CCHide action]];
			}
			break;
		default:;
		}

		/*life bar
		*/
		lifeBar_ = [[sprite_game_enemy_life_bar alloc] initSpriteGameEnemyLifeBar];
		[self addChild:lifeBar_];
		[lifeBar_ release];
		switch (type_)
		{
		case ENEMY_TYPE_0:
		case ENEMY_TYPE_1:
		case ENEMY_TYPE_2:
		case ENEMY_TYPE_3:
		case ENEMY_TYPE_4:
		case ENEMY_TYPE_5:
		case ENEMY_TYPE_6:
		case ENEMY_TYPE_7: lifeBar_.positionInPixels = g_CfgGameEnemyDataTable[type_].life_bar_position; break;
		case ENEMY_TYPE_BOSS_1: lifeBar_.positionInPixels = g_CfgGameBoss1Data.life_bar_position; break;
		case ENEMY_TYPE_BOSS_2: lifeBar_.positionInPixels = g_CfgGameBoss2Data.life_bar_position; break;
		case ENEMY_TYPE_BOSS_3: lifeBar_.positionInPixels = g_CfgGameBoss3Data.life_bar_position; break;
		default:;
		}

		/*effect
		*/
		switch (type_)
		{
		case ENEMY_TYPE_3:
			effectShockWave_ = [[CCSprite alloc] init];
			[self addChild:effectShockWave_];
			[effectShockWave_ release];
			break;
		case ENEMY_TYPE_5:
			effectCover_ = [[CCSprite alloc] init];
			[self addChild:effectCover_];
			[effectCover_ release];
			break;
		case ENEMY_TYPE_6:
			effectMouth_ = [[CCSprite alloc] init];
			[self addChild:effectMouth_];
			[effectMouth_ release];
			effectMouth_.positionInPixels = ccp(50, 100);
			break;
		case ENEMY_TYPE_7:
			effectMosquito_ = [[CCSprite alloc] init];
			[self addChild:effectMosquito_];
			[effectMosquito_ release];
			effectMosquito_.positionInPixels = ccp(50, 100);
			break;
		default:
			effectCover_ = nil;
			effectMouth_ = nil;
			effectMosquito_ = nil;
		}

		/*flag
		*/
		touchState_ = ENEMY_TOUCH_TYPE_INVALID;
		switch (type_)
		{
		case ENEMY_TYPE_0:
		case ENEMY_TYPE_1:
		case ENEMY_TYPE_2:
		case ENEMY_TYPE_3:
		case ENEMY_TYPE_4:
		case ENEMY_TYPE_5:
		case ENEMY_TYPE_6:
		case ENEMY_TYPE_7: flagTimeStopValid_ = true; break;
		case ENEMY_TYPE_BOSS_1:
			flagTimeStopValid_ = false;
			flagBoss1Stage_ = BOSS_1_STAGE_1;
			flagBoss1StrongAttackTotalDropBombCount_ = 0;
			flagBoss1StrongAttackDropBombCount_ = 0;
			flagBoss1StrongAttackDropBombOffset_ = 0.0f;
			break;
		case ENEMY_TYPE_BOSS_2:
			flagTimeStopValid_ = false;
			flagBoss2Stage_ = BOSS_2_STAGE_1;
			[self StartTimerBoss2StartStrongAttack];
			break;
		case ENEMY_TYPE_BOSS_3:
			flagTimeStopValid_ = false;
			flagBoss3Stage_ = BOSS_3_STAGE_1;
			flagBoss3SpecialAttackEyeOpenIndex_ = 0;
			flagBoss3SpecialQte_ = false;
			[g_LayerGameObject RegisterTouchEvent:self];
			break;
		}

		/*handle
		*/
		mouthHeartHandle_ = nil;
		mosquitoHeartHandle_ = nil;
		boss3Handle_ = nil;
		boss3SlaveLeftHandle_ = nil;
		boss3SlaveRightHandle_ = nil;

		/*music
		*/
		switch (type_)
		{
		case ENEMY_TYPE_BOSS_1:
		case ENEMY_TYPE_BOSS_2:
		case ENEMY_TYPE_BOSS_3:
			MusicPlayGameBossStage1();
			break;
		}
	}
	return self;
}

- (void)dealloc
{
	switch (type_)
	{
	case ENEMY_TYPE_BOSS_1: break;
	case ENEMY_TYPE_BOSS_3:[g_LayerGameObject UnregisterTouchEvent:self]; break;
	default:;
	}



	/*clear box2d
	*/
	if (NULL != box2dBody_)
	{
		[g_LayerGameObject PutBox2dBodyToDestroyPool:box2dBody_];
		box2dBody_ = NULL;
	}

	[super dealloc];
}

- (void)tick:(ccTime)Time
{

}


- (void)CreateBody
{
	int i;
	int _VertexCount;
	float _Ratio;
	b2Vec2 *_Vertex;
	b2BodyDef _BodyDef;
	b2PolygonShape _PolygonShape;
	b2FixtureDef _FixtureDef;

	_BodyDef.type = b2_dynamicBody;
	box2dBody_ = CMgrGamePhysics::World()->CreateBody(&_BodyDef);
	_Ratio = 1 / CMgrGamePhysics::Ratio();
	_FixtureDef.density = 1.0f;
	_FixtureDef.isSensor = true;
	switch (type_)
	{
	case ENEMY_TYPE_0:
	case ENEMY_TYPE_1:
	case ENEMY_TYPE_2:
	case ENEMY_TYPE_3:
	case ENEMY_TYPE_4:
	case ENEMY_TYPE_6:
	case ENEMY_TYPE_7:
		_VertexCount = g_CfgGameEnemyDataTable[type_].box2d_collision_point_table_body.size();
		_Vertex = ptCreateCollisionVertex(&g_CfgGameEnemyDataTable[type_].box2d_collision_point_table_body);
		for (i = 0; i < _VertexCount; ++i)
		{
			_Vertex[i] = ptScaleVector_same(_Vertex[i], _Ratio);
		}
		_PolygonShape.Set(_Vertex, _VertexCount);
		free(_Vertex);
		_FixtureDef.shape = &_PolygonShape;
		fixtureBody_ = box2dBody_->CreateFixture(&_FixtureDef);
		break;
	case ENEMY_TYPE_5:
		/*body*/
		_VertexCount = g_CfgGameEnemyDataTable[type_].box2d_collision_point_table_body.size();
		_Vertex = ptCreateCollisionVertex(&g_CfgGameEnemyDataTable[type_].box2d_collision_point_table_body);
		for (i = 0; i < _VertexCount; ++i)
		{
			_Vertex[i] = ptScaleVector_same(_Vertex[i], _Ratio);
		}
		_PolygonShape.Set(_Vertex, _VertexCount);
		free(_Vertex);
		_FixtureDef.shape = &_PolygonShape;
		fixtureBody_ = box2dBody_->CreateFixture(&_FixtureDef);
		/*armor*/
		_VertexCount = g_CfgGameEnemyDataTable[type_].box2d_collision_point_table_armor.size();
		_Vertex = ptCreateCollisionVertex(&g_CfgGameEnemyDataTable[type_].box2d_collision_point_table_armor);
		for (i = 0; i < _VertexCount; ++i)
		{
			_Vertex[i] = ptScaleVector_same(_Vertex[i], _Ratio);
		}
		_PolygonShape.Set(_Vertex, _VertexCount);
		free(_Vertex);
		_FixtureDef.shape = &_PolygonShape;
		fixtureArmor_ = box2dBody_->CreateFixture(&_FixtureDef);
		break;
	case ENEMY_TYPE_BOSS_1:
		/*head
		*/
		_VertexCount = g_CfgGameBoss1Data.box2d_collision_point_table_head.size();
		_Vertex = ptCreateCollisionVertex(&g_CfgGameBoss1Data.box2d_collision_point_table_head);
		for (i = 0; i < _VertexCount; i++)
		{
			_Vertex[i] = ptScaleVector_same(_Vertex[i], _Ratio);
		}
		_PolygonShape.Set(_Vertex, _VertexCount);
		free(_Vertex);
		_FixtureDef.shape = &_PolygonShape;
		fixtureBoss1Head_ = box2dBody_->CreateFixture(&_FixtureDef);
		/*body
		*/
		_VertexCount = g_CfgGameBoss1Data.box2d_collision_point_table_body.size();
		_Vertex = ptCreateCollisionVertex(&g_CfgGameBoss1Data.box2d_collision_point_table_body);
		for (i = 0; i < _VertexCount; i++)
		{
			_Vertex[i] = ptScaleVector_same(_Vertex[i], _Ratio);
		}
		_PolygonShape.Set(_Vertex, _VertexCount);
		free(_Vertex);
		_FixtureDef.shape = &_PolygonShape;
		fixtureBoss1Body_ = box2dBody_->CreateFixture(&_FixtureDef);
		break;
	case ENEMY_TYPE_BOSS_2:
		_VertexCount = g_CfgGameBoss2Data.box2d_collision_point_table_body.size();
		_Vertex = ptCreateCollisionVertex(&g_CfgGameBoss2Data.box2d_collision_point_table_body);
		for (i = 0; i < _VertexCount; ++i)
		{
			_Vertex[i] = ptScaleVector_same(_Vertex[i], _Ratio);
		}
		_PolygonShape.Set(_Vertex, _VertexCount);
		free(_Vertex);
		_FixtureDef.shape = &_PolygonShape;
		fixtureBody_ = box2dBody_->CreateFixture(&_FixtureDef);
		_FixtureDef.shape = &_PolygonShape;
		fixtureBoss3Head_ = box2dBody_->CreateFixture(&_FixtureDef);
		break;
	case ENEMY_TYPE_BOSS_3:
		/*head
		*/
		_VertexCount = g_CfgGameBoss3Data.box2d_collision_point_table_head.size();
		_Vertex = ptCreateCollisionVertex(&g_CfgGameBoss3Data.box2d_collision_point_table_head);
		for (i = 0; i < _VertexCount; ++i)
		{
			_Vertex[i] = ptScaleVector_same(_Vertex[i], _Ratio);
		}
		_PolygonShape.Set(_Vertex, _VertexCount);
		free(_Vertex);
		_FixtureDef.shape = &_PolygonShape;
		fixtureBoss3Head_ = box2dBody_->CreateFixture(&_FixtureDef);
		/*body
		*/
		_VertexCount = g_CfgGameBoss3Data.box2d_collision_point_table_body.size();
		_Vertex = ptCreateCollisionVertex(&g_CfgGameBoss3Data.box2d_collision_point_table_body);
		for (i = 0; i < _VertexCount; ++i)
		{
			_Vertex[i] = ptScaleVector_same(_Vertex[i], _Ratio);
		}
		_PolygonShape.Set(_Vertex, _VertexCount);
		free(_Vertex);
		_FixtureDef.shape = &_PolygonShape;
		fixtureBoss3Body_ = box2dBody_->CreateFixture(&_FixtureDef);
		/*ass
		*/
		_VertexCount = g_CfgGameBoss3Data.box2d_collision_point_table_ass.size();
		_Vertex = ptCreateCollisionVertex(&g_CfgGameBoss3Data.box2d_collision_point_table_ass);
		for (i = 0; i < _VertexCount; ++i)
		{
			_Vertex[i] = ptScaleVector_same(_Vertex[i], _Ratio);
		}
		_PolygonShape.Set(_Vertex, _VertexCount);
		free(_Vertex);
		_FixtureDef.shape = &_PolygonShape;
		fixtureBoss3Ass_ = box2dBody_->CreateFixture(&_FixtureDef);
		break;
	default:;
	}
}

- (void)DestroyBody
{
	std::list<sprite_game_enemy_skull *>::iterator _Iter;

	/*body
	*/
	if (NULL != box2dBody_)
	{
		[g_LayerGameObject PutBox2dBodyToDestroyPool:box2dBody_];
		box2dBody_ = NULL;
	}

	/*skull
	*/
	switch (type_)
	{
	case ENEMY_TYPE_BOSS_2:
		_Iter = skullList_.begin();
		for (; _Iter != skullList_.end(); _Iter++)
		{
			[*_Iter DestroyBody];
		}
		break;
	}
}

- (b2Vec2)ComputeBodyPosition
{
	return ptConvertCGPoint(ptScalePoint_same(self.positionInPixels, 1 / CMgrGamePhysics::Ratio()));
}

- (sprite_game_enemy_skull *)AddSkull:(CGPoint)Position And:(bool)FlagRotate
{
	sprite_game_enemy_skull *_Skull;

	_Skull = [[sprite_game_enemy_skull alloc] initSpriteGameEnemySkull];
	[self addChild:_Skull];
	[_Skull release];
	skullList_.push_back(_Skull);
	_Skull.positionInPixels = Position;
	_Skull.flagRotate = FlagRotate;
	return _Skull;
}

- (void)Pause
{
	int i;
	std::list<sprite_game_enemy_skull *>::iterator _SkullIter;

	switch (type_)
	{
	case ENEMY_TYPE_0:
	case ENEMY_TYPE_1:
	case ENEMY_TYPE_2:
	case ENEMY_TYPE_3:
	case ENEMY_TYPE_4:
	case ENEMY_TYPE_5:
	case ENEMY_TYPE_6:
	case ENEMY_TYPE_7:
		[self pauseSchedulerAndActions];
		[image_ pauseSchedulerAndActions];
		if (nil != effectMouth_)
		{
			[effectMouth_ pauseSchedulerAndActions];
		}
		if (nil != effectMosquito_)
		{
			[effectMosquito_ pauseSchedulerAndActions];
		}
		break;
	case ENEMY_TYPE_BOSS_1:
		[self pauseSchedulerAndActions];
		[image_ pauseSchedulerAndActions];
		[tailLeft_ Pause];
		[tailRight_ Pause];
		break;
	case ENEMY_TYPE_BOSS_2:
		[self pauseSchedulerAndActions];
		[image_ pauseSchedulerAndActions];
		_SkullIter = skullList_.begin();
		for (; _SkullIter != skullList_.end(); _SkullIter++)
		{
			[*_SkullIter Pause];
		}
		break;
	case ENEMY_TYPE_BOSS_3:
		[self pauseSchedulerAndActions];
		[image_ pauseSchedulerAndActions];
		for (i = 0; i < BOSS_3_QTE_EYE_COUNT; i++)
		{
			[eye_[i] Pause];
		}
		[boss3ChargeParticle_ pauseSchedulerAndActions];
		break;
	}
}

- (void)Resume
{
	int i;
	std::list<sprite_game_enemy_skull *>::iterator _SkullIter;

	switch (type_)
	{
	case ENEMY_TYPE_0:
	case ENEMY_TYPE_1:
	case ENEMY_TYPE_2:
	case ENEMY_TYPE_3:
	case ENEMY_TYPE_4:
	case ENEMY_TYPE_5:
	case ENEMY_TYPE_6:
	case ENEMY_TYPE_7:
		[self resumeSchedulerAndActions];
		[image_ resumeSchedulerAndActions];
		if (nil != effectMouth_)
		{
			[effectMouth_ resumeSchedulerAndActions];
		}
		if (nil != effectMosquito_)
		{
			[effectMosquito_ resumeSchedulerAndActions];
		}
		break;
	case ENEMY_TYPE_BOSS_1:
		[self resumeSchedulerAndActions];
		[image_ resumeSchedulerAndActions];
		[tailLeft_ Resume];
		[tailRight_ Resume];
		break;
	case ENEMY_TYPE_BOSS_2:
		[self resumeSchedulerAndActions];
		[image_ resumeSchedulerAndActions];
		_SkullIter = skullList_.begin();
		for (; _SkullIter != skullList_.end(); _SkullIter++)
		{
			[*_SkullIter Resume];
		}
		break;
	case ENEMY_TYPE_BOSS_3:
		[self resumeSchedulerAndActions];
		[image_ resumeSchedulerAndActions];
		for (i = 0; i < BOSS_3_QTE_EYE_COUNT; i++)
		{
			[eye_[i] Resume];
		}
		[boss3ChargeParticle_ resumeSchedulerAndActions];
		break;
	default:;
	}
}

- (void)EventTouchBegin:(CGPoint)Point
{}

- (void)EventTouchMove:(CGPoint)Point
{}

- (void)EventTouchEnd:(CGPoint)Point
{
	int i, j;
	UICenterRect _Rect;

	switch (touchState_)
	{
	case ENEMY_TOUCH_TYPE_INVALID: break;
	case ENEMY_TOUCH_TYPE_BOSS_3_QTE:
		Point = ccpSub(Point, self.positionInPixels);
		for (i = 0; i < BOSS_3_QTE_EYE_COUNT; i++)
		{
			_Rect.center = eye_[i].positionInPixels;
			_Rect.size = g_CfgGameBoss3Data.child_eye_size;
			if (uiPointInCenterRect(Point, _Rect) && !eye_[i].flagEyeClose)
			{
				if (i == flagBoss3SpecialAttackEyeOpenIndex_)
				{
					eye_[flagBoss3SpecialAttackEyeOpenIndex_].flagEyeClose = true;
					[eye_[flagBoss3SpecialAttackEyeOpenIndex_] ActionEyeClose];
					flagBoss3SpecialAttackEyeOpenIndex_--;
					if (flagBoss3SpecialAttackEyeOpenIndex_ < 0)
					{
						touchState_ = ENEMY_TOUCH_TYPE_INVALID;
						flagBoss3SpecialQte_ = true;
						/*mask color
						*/
						mask_.r = mask_.g = mask_.b = 0.9f;
					}
				}
				else
				{
					touchState_ = ENEMY_TOUCH_TYPE_INVALID;
					flagBoss3SpecialQte_ = false;
					mask_.color = ccRED;
					for (j = 0; j < BOSS_3_QTE_EYE_COUNT; j++)
					{
						if (!eye_[j].flagEyeClose)
						{
							[eye_[j] ActionEyeClose];
						}
					}
					/*mask color
					*/
					mask_.r = 1.0f;
					mask_.g = mask_.b = 0.0f;
				}
				break;
			}
		}
		break;
	default:;
	}
}

- (bool)IsBodyFixture:(b2Fixture *)Fixture
{
	return Fixture == fixtureBody_;
}

- (bool)IsArmorFixture:(b2Fixture *)Fixture
{
	return Fixture == fixtureArmor_;
}

- (bool)IsBoss1HeadFixture:(b2Fixture *)Fixture
{
	return fixtureBoss1Head_ == Fixture;
}

- (bool)IsBoss1BodyFixture:(b2Fixture *)Fixture
{
	return fixtureBoss1Body_ == Fixture;
}

- (bool)IsBoss1TailFixture:(b2Fixture *)Fixture
{
	bool _Ret;

	_Ret = false;
	if (tailLeft_.flagActive && (tailLeft_.fixture == Fixture))
	{
		_Ret = true;
		goto RETURN_;
	}
	if (tailRight_.flagActive && (tailRight_.fixture == Fixture))
	{
		_Ret = true;
		goto RETURN_;
	}

RETURN_:
	return _Ret;
}

- (bool)IsBoss2SkullFixture:(b2Fixture *)Fixture
{
	std::list<sprite_game_enemy_skull *>::iterator _Iter;

	_Iter = skullList_.begin();
	for (; skullList_.end() != _Iter; ++_Iter)
	{
		if (Fixture == (*_Iter).fixture)
		{
			return true;
		}
	}
	return false;
}

- (bool)IsBoss3HeadFixture:(b2Fixture *)Fixture
{
	return fixtureBoss3Head_ == Fixture;
}

- (bool)IsBoss3BodyFixture:(b2Fixture *)Fixture
{
	return fixtureBoss3Body_ == Fixture;
}

- (bool)IsBoss3AssFixture:(b2Fixture *)Fixture
{
	return fixtureBoss3Ass_ == Fixture;
}

- (bool)IsInvincible
{
	switch (type_)
	{
	case ENEMY_TYPE_0:
	case ENEMY_TYPE_1:
	case ENEMY_TYPE_2:
	case ENEMY_TYPE_3:
	case ENEMY_TYPE_4:
	case ENEMY_TYPE_5:
	case ENEMY_TYPE_6:
	case ENEMY_TYPE_7: return false;

	case ENEMY_TYPE_BOSS_1:
		switch (state_)
		{
		case ENEMY_STATE_BOSS1_APPEAR: return true;

		case ENEMY_STATE_BOSS1_STAGE_CHANGE: return true;

		default: return false;
		}
	case ENEMY_TYPE_BOSS_2:
		switch (state_)
		{
		case ENEMY_STATE_BOSS2_APPEAR: return true;

		case ENEMY_STATE_BOSS2_STAGE_CHANGE: return true;

		default: return false;
		}
	case ENEMY_TYPE_BOSS_3:
		switch (state_)
		{
		case ENEMY_STATE_BOSS3_APPEAR: return true;

		case ENEMY_STATE_BOSS3_STAGE_CHANGE: return true;

		case ENEMY_STATE_BOSS3_SPECIAL_ATTACK: return true;

		default: return false;
		}
	default: return false;
	}
}

- (bool)Damage:(float)DamagePoint
{
	lifePoint_ -= DamagePoint;
	if (lifePoint_ <= 0.0f)
	{
		[lifeBar_ runAction:[CCHide action]];
		return true;
	}
	else
	{
		switch (type_)
		{
		case ENEMY_TYPE_0:
		case ENEMY_TYPE_1:
		case ENEMY_TYPE_2:
		case ENEMY_TYPE_3:
		case ENEMY_TYPE_4:
		case ENEMY_TYPE_5:
		case ENEMY_TYPE_6:
		case ENEMY_TYPE_7:[lifeBar_ SetPersent:lifePoint_ / (float)g_CfgGameEnemyDataTable[type_].life_point * 100.0f]; break;
		case ENEMY_TYPE_BOSS_1:
			switch (flagBoss1Stage_)
			{
			case BOSS_1_STAGE_1:
				if (lifePoint_ < (float)g_CfgGameBoss1Data.life_point * 0.6)
				{
					lifePoint_ = (float)g_CfgGameBoss1Data.life_point * 0.6;
					[self ActionBoss1StageChage];
				}
				break;
			case BOSS_1_STAGE_2:
				if (lifePoint_ < (float)g_CfgGameBoss1Data.life_point * 0.3)
				{
					lifePoint_ = (float)g_CfgGameBoss1Data.life_point * 0.3;
					[self ActionBoss1StageChage];
				}
				break;
			case BOSS_1_STAGE_3: break;
			default:;
			}
			[lifeBar_ SetPersent:lifePoint_ / (float)g_CfgGameBoss1Data.life_point * 100.0f];
			break;
		case ENEMY_TYPE_BOSS_2:
			switch (flagBoss2Stage_)
			{
			case BOSS_2_STAGE_1:
				if (lifePoint_ < (float)g_CfgGameBoss2Data.life_point * 0.6)
				{
					lifePoint_ = (float)g_CfgGameBoss2Data.life_point * 0.6;
					[self ActionBoss2Stage2];
				}
				break;
			case BOSS_2_STAGE_2:
				if (lifePoint_ < (float)g_CfgGameBoss2Data.life_point * 0.3)
				{
					lifePoint_ = (float)g_CfgGameBoss2Data.life_point * 0.3;
					[self ActionBoss2Stage3];
				}
				break;
			case BOSS_2_STAGE_3: break;
			default:;
			}
			[lifeBar_ SetPersent:lifePoint_ / (float)g_CfgGameBoss2Data.life_point * 100.0f];
			break;
		case ENEMY_TYPE_BOSS_3:
			switch (flagBoss3Stage_)
			{
			case BOSS_3_STAGE_1:
				if (lifePoint_ < (float)g_CfgGameBoss3Data.life_point * 0.6)
				{
					lifePoint_ = (float)g_CfgGameBoss3Data.life_point * 0.6;
					[self ActionBoss3StageChange];
				}
				break;
			case BOSS_3_STAGE_2:
				if (lifePoint_ < (float)g_CfgGameBoss3Data.life_point * 0.3)
				{
					lifePoint_ = (float)g_CfgGameBoss3Data.life_point * 0.3;
					[self ActionBoss3StageChange];
				}
				break;
			case BOSS_3_STAGE_3: break;
			default:;
			}
			[lifeBar_ SetPersent:lifePoint_ / (float)g_CfgGameBoss3Data.life_point * 100.0f];
			break;
		default:;
		}
		[self ActionDamageTint];
		return false;
	}
}

- (bool)DamageBoss1Tail:(float)DamagePoint And:(b2Fixture *)Fixture
{
	if (Fixture == tailLeft_.fixture)
	{
		if (tailLeft_.flagInvincible)
		{
			return false;
		}
		else
		{
			[tailLeft_ Damage:DamagePoint];
			return true;
		}
	}
	else if (Fixture == tailRight_.fixture)
	{
		if (tailRight_.flagInvincible)
		{
			return false;
		}
		else
		{
			[tailRight_ Damage:DamagePoint];
			return true;
		}
	}
	else
	{
		assert(false);
	}
}

- (bool)DamageBoss2Skull:(float)DamagePoint And:(b2Fixture *)Fixture
{
	std::list<sprite_game_enemy_skull *>::iterator _Iter;

	_Iter = skullList_.begin();
	for (; _Iter != skullList_.end(); ++_Iter)
	{
		if (((*_Iter).fixture == Fixture) && (*_Iter).flagWeakPoint)
		{
			[(*_Iter)StopActionWeakPoint];
			[self Damage:DamagePoint * 1.3f];
			[self ActionAttack];
			[self StartTimerBoss2StartStrongAttack];
			return true;
		}
	}
	return false;
}



- (sprite_game_heart *)GetFreeHeart
{
	float _Distance;
	sprite_game_heart *_Ret;
	std::list<sprite_game_heart *> *_Pool;
	std::list<sprite_game_heart *>::iterator _Iter;

	_Distance = 0.0f;
	_Ret = nil;
	_Pool = [g_LayerGameObject GetHeartPool];
	_Iter = _Pool->begin();
	for (; _Iter != _Pool->end(); _Iter++)
	{
		if ((false == (*_Iter).flagDark) &&
		    (false == (*_Iter).flagDie) &&
		    (false == (*_Iter).flagMouth) &&
		    (false == (*_Iter).flagMosquito) &&
		    (false == (*_Iter).flagSwirl))
		{
			if (nil == _Ret)
			{
				_Ret = *_Iter;
				_Distance = ptPointDistance_CGPoint(self.positionInPixels, (*_Iter).positionInPixels);
			}
			else if (_Distance > ptPointDistance_CGPoint(self.positionInPixels, (*_Iter).positionInPixels))
			{
				_Ret = *_Iter;
				_Distance = ptPointDistance_CGPoint(self.positionInPixels, (*_Iter).positionInPixels);
			}
		}
	}
	return _Ret;
}










@end

@implementation sprite_game_enemy_mask

@synthesize r = r_;
@synthesize g = g_;
@synthesize b = b_;
@synthesize flagFadeOut = flagFadeOut_;

- (id)initSpriteGameEnemyMask
{
	CCLabelTTF *_Line1;
	CCLabelTTF *_Line2;

	if ((self = [super init]))
	{
		image_ = [CCSprite spriteWithSpriteFrameName:[NSString stringWithUTF8String:g_CfgGameBoss3Data.ani_eye_open.path_table.back().c_str()]];
		[self addChild:image_];
		image_.scale = 3.0f;
		image_.opacity = 100;

		if (g_FlagChinese)
		{
			_Line1 = [CCLabelTTF labelWithString:@"按照相反的顺序点击恶魔之眼" fontName:@"ArialMT" fontSize:SPRITE_GAME_ENEMY_BOSS_3_MASK_FONT_SIZE];
		}
		else
		{
			_Line1 = [CCLabelTTF labelWithString:@"Tap the demon eyes by the reversed" fontName:@"ArialMT" fontSize:SPRITE_GAME_ENEMY_BOSS_3_MASK_FONT_SIZE];
		}
		[self addChild:_Line1];
		_Line1.anchorPoint = ccp(0.5f, 0.0f);

		if (g_FlagChinese)
		{
			_Line2 = [CCLabelTTF labelWithString:@"使丘比特从梦魇中醒过来." fontName:@"ArialMT" fontSize:SPRITE_GAME_ENEMY_BOSS_3_MASK_FONT_SIZE];
		}
		else
		{
			_Line2 = [CCLabelTTF labelWithString:@"opening sequence to awake cupid." fontName:@"ArialMT" fontSize:SPRITE_GAME_ENEMY_BOSS_3_MASK_FONT_SIZE];
		}
		[self addChild:_Line2];
		_Line2.anchorPoint = ccp(0.5f, 0.0f);

		_Line2.positionInPixels = ccp(g_ScrrenCenter.x, 0.0f);
		_Line1.positionInPixels = ccp(g_ScrrenCenter.x, 2 + _Line2.contentSizeInPixels.height);
	}
	return self;
}

- (void)draw
{
	UICenterRect _Rect;

	_Rect.size = g_ScrrenSize;
	_Rect.center = g_ScrrenCenter;
	glColor4f(r_, g_, b_, (float)self.opacity / (float)255);
	uiRenderRect(_Rect);
}

- (void)actionReady
{
	image_.scale = 3.0f;
	image_.opacity = 100;
	image_.positionInPixels = g_CfgGameBoss3Data.child_eye_position_table[4];
}

- (void)ActionFadeOut
{
	CCSequence *_Seq;
	id _ActionFadeOut;
	CCCallFuncN *_CallBackFadeOutOver;

	CCSequence *seqImage;
	CCSpawn *spaImage;
	id actionImageScale;
	id actionImageMove;

	_ActionFadeOut = [CCFadeTo actionWithDuration:2 opacity:0];
	_CallBackFadeOutOver = [CCCallFuncN actionWithTarget:self selector:@selector(CallBackActionFadeOutOver:)];
	_Seq = [CCSequence actions:_ActionFadeOut, _CallBackFadeOutOver, nil];
	[self runAction:_Seq];

	actionImageScale = [CCScaleTo actionWithDuration:2.0f scale:1.0f];
	actionImageMove = [action_move_in_pixel actionWithDuration:2.0f position:g_CfgGameScrrenArea[4].center];
	spaImage = [CCSpawn actions:actionImageScale, actionImageMove, nil];
	seqImage = [CCSequence actions:spaImage, nil];
	[image_ runAction:seqImage];
}

- (void)CallBackActionFadeOutOver:(id)Sender
{
	[self runAction:[CCHide action]];
	[parent_ CallBackBoss3SpecialAttackChildMaskFadeOutOver:self];
}

@end

@implementation sprite_game_enemy_eye

@synthesize flagEyeClose = flagEyeClose_;

- (id)initSpriteGameEnemyEye
{
	if ((self = [super init]))
	{
		image_ = [[CCSprite alloc] init];
		[self addChild:image_];
		[image_ release];
	}
	return self;
}

- (void)Pause
{
	[self pauseSchedulerAndActions];
	[image_ pauseSchedulerAndActions];
}

- (void)Resume
{
	[self resumeSchedulerAndActions];
	[image_ resumeSchedulerAndActions];
}

- (void)ActionEyeOpen
{
	CCSequence *_Seq;
	id _ActionEyeOpen;
	CCCallFuncN *_CallBackEyeOpen;

	_ActionEyeOpen = [CCAnimate actionWithAnimation:uiCreateAnimationObject(&g_CfgGameBoss3Data.ani_child_eye_open)];
	_CallBackEyeOpen = [CCCallFuncN actionWithTarget:self selector:@selector(CallBackActionEyeOpenOver:)];
	_Seq = [CCSequence actions:_ActionEyeOpen, _CallBackEyeOpen, nil];
	[image_ runAction:_Seq];
}

- (void)ActionEyeClose
{
	CCSequence *_Seq;
	id _ActionEyeClose;
	CCCallFuncN *_CallBackEyeClose;

	_ActionEyeClose = [CCAnimate actionWithAnimation:uiCreateAnimationObject(&g_CfgGameBoss3Data.ani_child_eye_close)];
	_CallBackEyeClose = [CCCallFuncN actionWithTarget:self selector:@selector(CallBackActionEyeCloseOver:)];
	_Seq = [CCSequence actions:_ActionEyeClose, _CallBackEyeClose, nil];
	[image_ runAction:_Seq];
}

- (void)CallBackActionEyeOpenOver:(id)Sender
{
	NSString *_Path;

	_Path = [NSString stringWithUTF8String:g_CfgGameBoss3Data.ani_child_eye_open.path_table.back().c_str()];
	[image_ setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:_Path]];
	[parent_ CallBackBoss3SpecialAttackChildEyeOpenOver:self];
}

- (void)CallBackActionEyeCloseOver:(id)Sender
{
	[self runAction:[CCHide action]];
	[parent_ CallBackBoss3SpecialAttackChildEyeCloseOver:self];
}

@end